package middleware

import (
	"context"
	"fmt"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/infraboard/mcube/v2/exception"
	"github.com/infraboard/mcube/v2/http/gin/response"
	"github.com/infraboard/mcube/v2/ioc/config/log"
	"gitlab.com/go-course-project/go17/vblog/apps/token"
)

// // HandlerFunc defines the handler used by gin middleware as return value.
// type HandlerFunc func(*Context)

// 补充我们的鉴权逻辑
// 1. 首先要获取Token, Cookie, Header, Authorization: 用于存放用户认证信息, Authorization: <token_type> <token_value>, Bearer xxxxxx
// 2. 校验Token
// 3. 注入用户信息
func Auth(c *gin.Context) {
	// 1. 获取Token
	accessToken := c.GetHeader("Authorization")
	tkList := strings.Split(accessToken, " ")

	accessToken = ""
	if len(tkList) == 2 {
		accessToken = tkList[1]
	}

	// 再尝试从cookie中获取
	if accessToken == "" {
		tc, err := c.Cookie(token.COOKIE_NAME)
		if err != nil {
			log.L().Error().Msgf("get cookie error, %s", err)
		} else {
			accessToken = tc
		}
	}

	// 2. 校验Token
	tk, err := token.GetService().ValidateToken(c.Request.Context(), token.NewValidateTokenRequest(accessToken))
	if err != nil {
		response.Failed(c, exception.NewUnauthorized("令牌校验失败: %s", err))
		c.Abort()
		return
	}

	// 3. 注入用户信息
	ctx := context.WithValue(c.Request.Context(), TokenCtxKey{}, tk)
	fmt.Println(tk)
	c.Request = c.Request.WithContext(ctx)
}

type TokenCtxKey struct{}

func GetTokenFromCtx(ctx context.Context) *token.Token {
	txCtx := ctx.Value(TokenCtxKey{})
	if txCtx == nil {
		return nil
	}
	return txCtx.(*token.Token)
}
